/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package damas.modelo;


import java.util.Iterator;
import java.util.LinkedList;

import damas.logicaYcontroladores.DamasLogica;
import damas.utils.Coordenadas;

import framework.IBasicState;
import framework.IStateAdversary;
import utils.ComparableInt;
import utils.IComparable;
import utils.Pair;

/**
 *
 * @author <COMPLETAR AUTOR>
 */
public class DamasEstado implements IStateAdversary
{
    public static final int NEGRA = 3;
    public static final int ROJA = -3;
    public static final int DAMA = 5;
    public static final int FONDO_NEGRO = 1;
    public static final int FONDO_BLANCO = 2;

    DamasEstado parent;
    private boolean isMin;
    private boolean isMax;

    protected int[][] fondo;
    int fichasRojasComidas;
    int fichasNegrasComidas;
	private DamasLogica logica;

    public DamasEstado(DamasLogica logica)
    {
    	this.logica = logica;
        setMax();
        fondo = fondoTablero();
        configurarTableroInicial();
    }
    
    public DamasEstado()
    {
        setMax();
        fondo = fondoTablero();
        configurarTableroInicial();
    }
    
    @Override
    public boolean minWins()
    {
    	boolean result = false;
    	int color = logica.colorJugadorActual(); 
    	if(color == ROJA && fichasComidas(NEGRA) == 12)
    		result = true;
    	if(color == NEGRA && fichasComidas(ROJA) == 12)
    		result = true;
    		
        return result;
    }

    @Override
    public boolean maxWins()
    {
    	boolean result = false;
    	int color = logica.colorJugadorActual(); 
    	if(fichasComidas(color) == 12)
    		result = true;
    		
        return result;
    }

    @Override
    public boolean isMax()
    {
        return isMax;
    }

    @Override
    public boolean isMin()
    {
        return isMin;
    }

    @Override
    public void setMax()
    {
        isMax = true;
        isMin = false;
    }

    @Override
    public void setMin()
    {
        isMin = true;
        isMax = false;
    }

    @Override
    public void changeLevel()
    {
        if (isMin())
            setMax();
        else
            setMin();
    }

    @Override
    public IComparable evaluate()
    {
        int result;
        
       // int comer = (logica != null) ? movimientosQueHabilitaranParaComer(logica.colorJugadorActual()).size() : 0;
        
        if (isMax() && logica.colorJugadorActual() == NEGRA)
            result = fichasComidas(ROJA);// - fichasComidas(NEGRA);
        else if (isMax() && logica.colorJugadorActual() == ROJA)
            result = fichasComidas(NEGRA);//- fichasComidas(ROJA) ;
        else if (isMin() && logica.colorJugadorActual() == ROJA)
        	result = fichasComidas(ROJA);// -  fichasComidas(NEGRA);
        else
        	result = fichasComidas(NEGRA);// - fichasComidas(ROJA);

        //result += comer; 

        return new ComparableInt(result);
    }

    @Override
    public IComparable minVal()
    {
        return new ComparableInt(-1000);//no come ninguna ficha
    }

    @Override
    public IComparable maxVal()
    {
        return new ComparableInt(1250);//comio todas las fichas
    }

    @Override
    public IBasicState getParent()
    {
        return this.parent;
    }

    @Override
    public void setParent(IBasicState parent)
    {
        this.parent = (DamasEstado)parent;
    }

    @Override
    public boolean isFinal()
    {
        return minWins() || maxWins();
    }

    @Override
    public boolean success()
    {
        return minWins() || maxWins();
    }

    @Override
    public boolean repOk()
    {
        return true;
    }

    public DamasEstado clone()
    {
        DamasEstado result = new DamasEstado(logica);

        for (int fil = 0; fil < 8; fil++)
            for (int col = 0; col < 8; col++)
                result.fondo[fil][col] = this.fondo[fil][col];

        result.parent = this;
        result.fichasNegrasComidas = this.fichasNegrasComidas;
        result.fichasRojasComidas  = this.fichasRojasComidas;
        result.isMax = this.isMax;
        result.isMin = this.isMin;

        return result;
    }


    private static int[][] fondoTablero()
    {
        return new int[][]
        {
        		{FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO},
        		{FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO},
        		{FONDO_BLANCO,FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO},
        		{FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO},
        		{FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO},
        		{FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO},
        		{FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO},
        		{FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO, FONDO_NEGRO, FONDO_BLANCO},
        };
    }

    /**
     * pre: el tablero tiene solo los colores de fondo
     * pos: el tablero con las fichas negras y rojas en sus posiciones iniciales reglamentarias
     */
    private void configurarTableroInicial()
    {
        for (int row = 0; row < 8; row++)
            for (int col = 0; col < 8; col++)
            {
                if (row < 3)
                    if (((row % 2 == 0) && (col % 2 != 0)) || ((row % 2 != 0) && (col % 2 == 0))) //fila par y columna par
                        fondo [row][col] *= NEGRA;
                if (row > 4)
                    if (((row % 2 == 0) && (col % 2 != 0)) || ((row % 2 != 0) && (col % 2 == 0))) //fila impar y columna impar
                        fondo [row][col] *= ROJA;
            }
    }

    public boolean mover(Pair<Integer, Integer> inicio, Pair<Integer, Integer> destino)
    {
        boolean result = false;
        int isDama = debeSerDama(destino,inicio) ? DAMA : 1; // fijarse que no sea dama todavia
        fondo[destino.getFirstElem()][destino.getSecondElem()] = fichaEn(inicio) * fondoEn(destino) * isDama;
        fondo[inicio.getFirstElem() ][inicio.getSecondElem() ] = fondoEn(inicio);

        if (!Coordenadas.cercanos(inicio, destino))  //cercanos devuelve true si la dist(inicio, fin) == raiz(2)
        {
            eliminarComido(inicio, destino);
            if (posicionPostComida(destino) != null)
                result = true;
        }
        
        return result;
    }

    private boolean debeSerDama(Pair<Integer, Integer> destino, Pair<Integer, Integer> origen) 
    {
    	boolean result = false;
    	if(!esDama(destino)){	
	    	if(destino.getFirstElem().compareTo(0) == 0 && fichaEn(origen) == ROJA)
	    		result = true;
	    	if(destino.getFirstElem().compareTo(7) == 0 && fichaEn(origen) == NEGRA)
	    		result = true;
    	}
    	return result;
	}

	private void eliminarComido(Pair<Integer, Integer> inicio, Pair<Integer, Integer> destino)
    {
        int xInicio  = inicio.getFirstElem();
        int yInicio  = inicio.getSecondElem();
        int xDestino = destino.getFirstElem();
        int yDestino = destino.getSecondElem();
        int xborrado = 0;
        int yborrado = 0;

        if (xDestino < xInicio && yDestino < yInicio)
        {
            xborrado = xInicio - 1;
            yborrado = yInicio - 1;
        }
        if (xDestino < xInicio && yDestino > yInicio)
        {
            xborrado = xInicio - 1;
            yborrado = yInicio + 1;
        }
        if (xDestino > xInicio && yDestino < yInicio)
        {
            xborrado = xInicio + 1;
            yborrado = yInicio - 1;
        }
        if (xDestino > xInicio && yDestino > yInicio)
        {
            xborrado = xInicio + 1;
            yborrado = yInicio + 1;
        }

        if (fichaEn(xborrado, yborrado) == ROJA)
            fichasRojasComidas++;
        else//si una ficha negra fue comida
            fichasNegrasComidas++;

        //le dejo solo el fondo, es decir saco la ficha
        fondo[xborrado][yborrado] = fondoEn(xborrado, yborrado);
    }

    public LinkedList<Pair<Integer, Integer>> puedeComerDesde(int color)
    {
        LinkedList<Pair<Integer, Integer>> l = new LinkedList<Pair<Integer, Integer>>();
        Pair<Integer, Integer> p = null;

        for (int fil = 0; fil < 8; fil++)
            for (int col = 0; col < 8; col++)
                if (fichaEn(fil, col) == color && puedeComer(fil, col))
                {
                    p = new Pair<Integer, Integer>(fil, col);
                    l.add(p);
                }

        return l;
    }


    public int fondoEn(Pair<Integer, Integer> pos)
    {
        return fondoEn(pos.getFirstElem(), pos.getSecondElem());
    }

    public int fondoEn(int fil, int col)
    {
        int result;

        if (fondo[fil][col] % FONDO_BLANCO == 0)
            result = FONDO_BLANCO;
        else
            result = FONDO_NEGRO;

        return result;
    }

    public int fichaEn(int fila, int columna)
    {
        int valor = fondo[fila][columna];
        int result;

        if (valor == FONDO_BLANCO || valor == FONDO_NEGRO)
            result = 0;
        else if (valor < 0)
            result = (valor == -3) ? ROJA : DAMA*ROJA;
        else
            result = (valor == 3) ? NEGRA : DAMA*NEGRA;

        return result;
    }

    public int fichaEn(Pair<Integer, Integer> pos)
    {
        return fichaEn(pos.getFirstElem(), pos.getSecondElem());
    }

    private Pair<Integer, Integer> posicionPostComida(int fila, int col)
    {
        Pair<Integer, Integer> fichaActual = new Pair<Integer, Integer>(fila, col);
        int fichaColor = fichaEn(fichaActual);

        Pair<Integer, Integer> diagUpRight    = new Pair<Integer, Integer> (fila - 1, col + 1);
        Pair<Integer, Integer> diagUpLeft     = new Pair<Integer, Integer> (fila - 1, col - 1);
        Pair<Integer, Integer> diagDownRight  = new Pair<Integer, Integer> (fila + 1, col + 1);
        Pair<Integer, Integer> diagDownLeft   = new Pair<Integer, Integer> (fila + 1, col - 1);

        Pair<Integer, Integer> diagUpRightD   = new Pair<Integer, Integer> (fila - 2, col + 2);
        Pair<Integer, Integer> diagUpLeftD    = new Pair<Integer, Integer> (fila - 2, col - 2);
        Pair<Integer, Integer> diagDownRightD = new Pair<Integer, Integer> (fila + 2, col + 2);
        Pair<Integer, Integer> diagDownLeftD  = new Pair<Integer, Integer> (fila + 2, col - 2);

        Pair<Integer, Integer> result         = null;

        if (coordenadaValida(diagUpRightD) && Coordenadas.elMovEsPaArriba(fichaActual, diagUpRightD)   && fichaColor ==ROJA && fichaEn(diagUpRight) >= NEGRA && fichaEn(diagUpRightD) == 0)
            result = diagUpRightD;
        if (coordenadaValida(diagUpLeftD) && Coordenadas.elMovEsPaArriba(fichaActual, diagUpLeftD)    && fichaColor == ROJA && fichaEn(diagUpLeft)  >= NEGRA && fichaEn(diagUpLeftD) == 0)
            result = diagUpLeftD;
        if (coordenadaValida(diagDownRightD) && fichaColor == DAMA*ROJA && fichaEn(diagDownRight) >= NEGRA && fichaEn(diagDownRightD) == 0)
            result = diagDownRightD;
        if (coordenadaValida(diagDownLeftD)  && fichaColor == DAMA*ROJA &&  fichaEn(diagDownLeft) >= NEGRA && fichaEn(diagDownLeftD) == 0)
            result = diagDownLeftD;

        if (coordenadaValida(diagDownRightD) && Coordenadas.elMovEsPaAbajo(fichaActual, diagDownRightD)  && fichaColor == NEGRA &&  fichaEn(diagDownRight) <= ROJA && fichaEn(diagDownRightD) == 0)
            result = diagDownRightD;
        if (coordenadaValida(diagDownLeftD)  && Coordenadas.elMovEsPaAbajo(fichaActual, diagDownLeftD) && fichaColor == NEGRA && fichaEn(diagDownLeft)   <= ROJA && fichaEn(diagDownLeftD)  == 0)
            result = diagDownLeftD;
        if (coordenadaValida(diagUpRightD)   && fichaColor == DAMA*NEGRA && fichaEn(diagUpRight) <= ROJA && fichaEn(diagUpRightD) == 0)
            result = diagUpRightD;
        if (coordenadaValida(diagUpLeftD)    && fichaColor == DAMA*NEGRA && fichaEn(diagUpLeft) <= ROJA  && fichaEn(diagUpLeftD) == 0)
            result = diagUpLeftD;

        return result;
    }

    public boolean puedeComer(Pair<Integer, Integer> pos)
    {
        return puedeComer(pos.getFirstElem(), pos.getSecondElem());
    }

    public Pair<Integer, Integer> posicionPostComida(Pair<Integer, Integer> pos)
    {
        return posicionPostComida(pos.getFirstElem(), pos.getSecondElem());
    }

    private boolean puedeComer(int fila, int col)
    {
        Pair<Integer, Integer> fichaActual = new Pair<Integer, Integer>(fila, col);
        int fichaColor = fichaEn(fichaActual);

        Pair<Integer, Integer> diagUpRight    = new Pair<Integer, Integer> (fila - 1, col + 1);
        Pair<Integer, Integer> diagUpLeft     = new Pair<Integer, Integer> (fila - 1, col - 1);
        Pair<Integer, Integer> diagDownRight  = new Pair<Integer, Integer> (fila + 1, col + 1);
        Pair<Integer, Integer> diagDownLeft   = new Pair<Integer, Integer> (fila + 1, col - 1);

        Pair<Integer, Integer> diagUpRightD   = new Pair<Integer, Integer> (fila - 2, col + 2);
        Pair<Integer, Integer> diagUpLeftD    = new Pair<Integer, Integer> (fila - 2, col - 2);
        Pair<Integer, Integer> diagDownRightD = new Pair<Integer, Integer> (fila + 2, col + 2);
        Pair<Integer, Integer> diagDownLeftD  = new Pair<Integer, Integer> (fila + 2, col - 2);

        boolean result = false;

        result = result || (coordenadaValida(diagUpRightD)   && Coordenadas.elMovEsPaArriba(fichaActual, diagUpRightD)  && fichaColor == ROJA  && (fichaEn(diagUpRight)   >= NEGRA) && fichaEn(diagUpRightD)   == 0);
        result = result || (coordenadaValida(diagUpLeftD)    && Coordenadas.elMovEsPaArriba(fichaActual, diagUpLeftD)   && fichaColor == ROJA  && (fichaEn(diagUpLeft)    >= NEGRA)&& fichaEn(diagUpLeftD)    == 0);
        result = result || (coordenadaValida(diagDownRightD) && fichaColor == ROJA*DAMA             && (fichaEn(diagDownRight)  >= NEGRA)&& fichaEn(diagDownRightD) == 0);
        result = result || (coordenadaValida(diagDownLeftD)  && fichaColor == ROJA*DAMA             && (fichaEn(diagDownLeft)   >= NEGRA)&& fichaEn(diagDownLeftD)  == 0);
        result = result || (coordenadaValida(diagDownRightD) && Coordenadas.elMovEsPaAbajo(fichaActual, diagDownRightD)  && fichaColor == NEGRA && (fichaEn(diagDownRight) == ROJA || fichaEn(diagDownRight) == DAMA*ROJA)  && fichaEn(diagDownRightD) == 0);
        result = result || (coordenadaValida(diagDownLeftD)  && Coordenadas.elMovEsPaAbajo(fichaActual, diagDownLeftD )  && fichaColor == NEGRA && (fichaEn(diagDownLeft)  == ROJA || fichaEn(diagDownLeft)  == DAMA*ROJA )&& fichaEn(diagDownLeftD)  == 0);
        result = result || (coordenadaValida(diagUpRightD)   && fichaColor == NEGRA*DAMA             && (fichaEn(diagUpRight)    == ROJA || fichaEn(diagUpRight)    == DAMA*ROJA) && fichaEn(diagUpRightD)   == 0);
        result = result || (coordenadaValida(diagUpLeftD)    && fichaColor == NEGRA*DAMA             && (fichaEn(diagUpLeft)     == ROJA || fichaEn(diagUpLeft)     == DAMA*ROJA)&& fichaEn(diagUpLeftD)    == 0);

        return result;
    }

    private static boolean coordenadaValida(Pair<Integer, Integer> par)
    {
        return Coordenadas.coordenadaValida(par);
    }

    public boolean esDama(Pair<Integer, Integer> pos)
    {
        boolean isDamaNegra = false;
        boolean isDamaRoja  = false;

        isDamaNegra = fondo[pos.getFirstElem()][pos.getSecondElem()] == DAMA * NEGRA * FONDO_NEGRO;
        isDamaRoja  = fondo[pos.getFirstElem()][pos.getSecondElem()] == DAMA * ROJA  * FONDO_NEGRO;

        return isDamaNegra || isDamaRoja;
    }

    /**
     * cuantas fichas del rival comio el jugador que tiene sus fichas de color: color
     */
    public int fichasComidas(int color)
    {
        int result;

        if (color == NEGRA)
            result = fichasRojasComidas;
        else
            result = fichasNegrasComidas;

        return result;
    }

    public boolean vacio(Pair<Integer, Integer> pos)
    {
        return fondo[pos.getFirstElem()][pos.getSecondElem()] == FONDO_BLANCO || fondo[pos.getFirstElem()][pos.getSecondElem()] == FONDO_NEGRO;
    }

    public void reset()
    {
        fondo = fondoTablero();
        configurarTableroInicial();
        fichasNegrasComidas = 0;
        fichasRojasComidas = 0;
    }

    public LinkedList<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> movimientosQueHabilitaranParaComer(int color)
    {
    	LinkedList<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> l = movimientosPosibles(color);
    	Pair<Pair<Integer, Integer>, Pair<Integer, Integer>> p = null;

    	for (Pair<Pair<Integer, Integer>, Pair<Integer, Integer>> mov : l)
        {
            if (puedeComer(mov.getFirstElem()))
            {
            	p = new Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>();
            	p.setFirstElem(mov.getFirstElem());
            	p.setSecondElem(mov.getSecondElem());
            	l.add(p);
            }
        }
    	return l;
    }
    
    
    

    public LinkedList<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> movimientosPosibles(int color)
    {
        Pair<Integer, Integer> inicio = null;
        Pair<Integer, Integer> destino = null;

        LinkedList<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> lista = new  LinkedList<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>>();
        for (int row = 0; row < 8; row++)
        {
            for (int col = 0; col < 8; col++)
            {
                if (fondo[row] [col] == color || fondo[row] [col] == DAMA*color) //CAMBIO REALIZADO
                {
                    Pair<Pair<Integer, Integer>, Pair<Integer, Integer>> movimiento = new Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>();
                    inicio = new Pair<Integer, Integer>();
                    inicio.setFirstElem(row);
                    inicio.setSecondElem(col);

                    destino = diagUpRight(inicio);
                    if (movidaValida(inicio, destino))     //ANALIZO LAS 8 POSIBILIDADES
                    {
                        movimiento.setFirstElem(inicio);
                        movimiento.setSecondElem(destino);
                        lista.add(movimiento);
                    }

                    destino = diagUpLeft(inicio);
                    if (movidaValida(inicio, destino))
                    {
                        movimiento.setFirstElem(inicio);
                        movimiento.setSecondElem(destino);
                        lista.add(movimiento);
                    }

                    destino = diagDownRight(inicio);
                    if (movidaValida(inicio, destino))
                    {
                        movimiento.setFirstElem(inicio);
                        movimiento.setSecondElem(destino);
                        lista.add(movimiento);
                    }

                    destino = diagDownLeft(inicio);
                    if (movidaValida(inicio, destino))
                    {
                        movimiento.setFirstElem(inicio);
                        movimiento.setSecondElem(destino);
                        lista.add(movimiento);
                    }

                    destino = diagUpRightD(inicio);
                    if (movidaValida(inicio, destino))
                    {
                        movimiento.setFirstElem(inicio);
                        movimiento.setSecondElem(destino);
                        lista.add(movimiento);
                    }
                    destino = diagUpLeftD(inicio);
                    if (movidaValida(inicio, destino))
                    {
                        movimiento.setFirstElem(inicio);
                        movimiento.setSecondElem(destino);
                        lista.add(movimiento);
                    }
                    destino = diagDownRightD(inicio);
                    if (movidaValida(inicio, destino))
                    {
                        movimiento.setFirstElem(inicio);
                        movimiento.setSecondElem(destino);
                        lista.add(movimiento);
                    }
                    destino = diagDownLeftD(inicio);
                    if (movidaValida(inicio, destino))
                    {
                        movimiento.setFirstElem(inicio);
                        movimiento.setSecondElem(destino);
                        lista.add(movimiento);
                    }
                }
            }
        }
        return lista;
    }

    /**
     * Verifica una movida utilizando datos del estado (DamasEstado)
     * @param inicio : la posici�n de la ficha a mover : {@code Pair<Integer,Integer>}
     * @param destino : la posici�n a la cual se mueve : {@code Pair<Integer,Integer>}
     * @return true sii la movida es v�lida
     */
    private boolean movidaValida(Pair<Integer, Integer> inicio, Pair<Integer, Integer> destino)
    {
        boolean result = true;
        Pair<Integer, Integer> pos = null;

        if (coordenadaValida(inicio) && coordenadaValida(destino) && fichaEn(destino) == 0)
        {
            if (fondoEn(destino) != FONDO_NEGRO)
                result = false;

            if (puedeComerYNoLoHace(inicio))
                result = false;
        	
            if (Coordenadas.cercanos(inicio, destino))
            {
                if (!esDama(inicio))
                {
                    if (fichaEn(inicio) == ROJA)
                        result = result && Coordenadas.elMovEsPaArriba(inicio, destino);
                    else //si es negro
                        result = result && Coordenadas.elMovEsPaAbajo(inicio, destino);
                }
                else //SI ES DAMA (no importa el color)
                {
                		result = result && (Coordenadas.elMovEsPaArriba(inicio, destino) || Coordenadas.elMovEsPaAbajo(inicio, destino) ) ;
                }
            }
            else if (!puedeComer(inicio))
                result = false;


            result = result && !Coordenadas.isMovLateral(inicio, destino);

            if ((pos = posicionPostComida(inicio)) != null)// DESDE UNA POSICION PODES LLEGAR A TENER 2 PARA COMER??
            {
                if (!Coordenadas.iguales(pos, destino))
                    result = false;
            }
        }
        else
            result = false;
        
        return result;
    }

    public boolean puedeComerYNoLoHace(Pair<Integer, Integer> inicio)
    {
        LinkedList<Pair<Integer, Integer>> l = puedeComerDesde(fichaEn(inicio));

        return !pertenece(l, inicio) && l.size() > 0;
    }

    private static boolean pertenece(LinkedList<Pair<Integer, Integer>> list, Pair<Integer, Integer> elem)
    {
        boolean result = false;
        Iterator<Pair<Integer, Integer>> it = list.iterator();

        while (it.hasNext() && !result)
        {
            if (Coordenadas.iguales(it.next(), elem))
                result = true;
        }
        return result;
    }

    //diagonales sencillas
    public static Pair<Integer, Integer> diagUpRight(Pair<Integer, Integer> original)
    {
        return new Pair<Integer, Integer>(original.getFirstElem() - 1 , original.getSecondElem() + 1);
    }

    public static Pair<Integer, Integer> diagUpLeft(Pair<Integer, Integer> original)
    {
        return new Pair<Integer, Integer>(original.getFirstElem() - 1 , original.getSecondElem() - 1);
    }

    public static Pair<Integer, Integer> diagDownRight(Pair<Integer, Integer> original)
    {
        return new Pair<Integer, Integer>(original.getFirstElem() + 1 , original.getSecondElem() + 1);
    }

    public static Pair<Integer, Integer> diagDownLeft(Pair<Integer, Integer> original)
    {
        return new Pair<Integer, Integer>(original.getFirstElem() + 1 , original.getSecondElem() - 1);
    }
    //diagonales dobles
    public static Pair<Integer, Integer> diagUpRightD(Pair<Integer, Integer> original)
    {
        return new Pair<Integer, Integer>(original.getFirstElem() - 2 , original.getSecondElem() + 2);
    }

    public static Pair<Integer, Integer> diagUpLeftD(Pair<Integer, Integer> original)
    {
        return new Pair<Integer, Integer>(original.getFirstElem() - 2 , original.getSecondElem() - 2);
    }

    public static Pair<Integer, Integer> diagDownRightD(Pair<Integer, Integer> original)
    {
        return new Pair<Integer, Integer>(original.getFirstElem() + 2 , original.getSecondElem() + 2);
    }

    public static Pair<Integer, Integer> diagDownLeftD(Pair<Integer, Integer> original)
    {
        return new Pair<Integer, Integer>(original.getFirstElem() + 2 , original.getSecondElem() - 2);
    }
    
    public void setLogica(DamasLogica logica) {
		this.logica = logica;
	}
    
}
